package com.zzuli.yxy.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzuli.yxy.ListStringConverter;
import com.zzuli.yxy.dto.MenuDto;
import com.zzuli.yxy.entity.Menu;
import com.zzuli.yxy.result.R;
import com.zzuli.yxy.mapper.MenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzuli.yxy.service.MenuService;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

/**
 * @auther pony
 * @create 2023-03-30 19:09
 */
@Service
public class MenuServiceImpl  extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;
    /**
     * 获取全部权限信息
     * @return
     */
    @Override
    public R getAllMenu() {
        // 1、查询数据库，获取 权限 List 数据
        LambdaQueryWrapper<Menu> qw = new LambdaQueryWrapper<>();
        qw.eq(Menu::getStatus, 0);
        List<Menu> menuList = menuMapper.selectList(qw);
        // 2、对 权限 menuList 进行封装，封装成 menuDtoList
        ArrayList<MenuDto> menuDtoList = new ArrayList<>();
        for (Menu menu: menuList) {
            System.out.println(menu);
            MenuDto menuDto = new MenuDto();
            menuDto.setId(menu.getId());
            menuDto.setLabel(menu.getMenu());
            menuDto.setParentId(menu.getParentId());
            menuDtoList.add(menuDto);
        }
        // 3、转化为树形结构
        List<MenuDto> menuTree = getMenuDtoTree(menuDtoList);

        return R.success().message("所有权限信息").data("menuTree",menuTree);
    }

    /**
     * 获取权限管理分页信息
     * @param pageCurrent 当前页
     * @param pageSize 每页条数
     * @param name 关键字 非必传
     * @return
     */
    @Override
    public R getPage(Integer pageCurrent, Integer pageSize, String name) {
        //1、查询数据库，获取分页数据
        Page<Menu> pageInfo = new Page<>(pageCurrent, pageSize);
        LambdaQueryWrapper<Menu> qw = new LambdaQueryWrapper<>();
        qw.like(name!=null, Menu::getMenu, name);
        Page<Menu> menuPage = menuMapper.selectPage(pageInfo, qw);
        System.out.println("rolePage=" + menuPage);
        List<Menu> menuList = menuPage.getRecords();
        List<Menu> menuTree = getMenuTree(menuList);
        menuPage.setRecords(menuTree);
        return R.success().message("权限分页信息").data("menuPage", menuPage);
    }

    /**
     * 更改权限当前状态
     * @param status 状态码 0：正常 1：异常
     * @return
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<Menu> uw = new LambdaUpdateWrapper<>();
        uw.eq(Menu::getId, id);
        uw.set(Menu::getStatus, status);
        menuMapper.update(null, uw);
    }

    /**
     * 根据权限id，查询单个权限信息
     * @param id
     * @return
     */
    @Override
    public R selectOneById(Integer id) {
        LambdaQueryWrapper<Menu> qw = new LambdaQueryWrapper<>();
        qw.eq(Menu::getId, id);
        Menu menu = menuMapper.selectOne(qw);
        return R.success().message("根据id，查询单个权限数据").data("menu", menu);
    }

    /**
     * 修改权限信息
     * @param menu
     * @return
     */
    @Override
    public R updateMenu(Menu menu) {
        //1、判断角色名称和角色关键字是否重复
        LambdaQueryWrapper<Menu> qw = new LambdaQueryWrapper<>();
        qw.eq(Menu::getMenu, menu.getMenu());
        qw.last("limit 1");
        Menu selectResult = menuMapper.selectOne(qw);
        if (!Objects.isNull(selectResult)&&selectResult.getId()!=menu.getId()){
            return R.error().message("添加员工失败，权限名称重复！");
        }
        //2、修改用户信息
        int updateResult = menuMapper.updateById(menu);
        if (updateResult==1){
            return R.success().message("权限修改成功！");
        }
        return R.error().message("修改失败，请联系管理员！");
    }

    /**
     * 将 menuDtoList 转化为树形结构
     * @param menusList 员工权限列表
     * @return
     */
    private List<MenuDto> getMenuDtoTree(List<MenuDto> menusList) {
        //1、new 一个 List 集合，存放数据
        ArrayList<MenuDto> resultMenuList = new ArrayList<>();//权限列表

        for (MenuDto menu: menusList) {
            //2、继续遍历，寻找子节点
            for (MenuDto e: menusList) {
                if (e.getParentId().equals(menu.getId())){
                    menu.getChildren().add(e);
                }
            }
            //3、如果 ParentId = 0，表示此权限就是顶级父级菜单
            if (menu.getParentId()==0){
                resultMenuList.add(menu);
            }
        }
        return resultMenuList;
    }

    /**
     * 将 menuList 转化为树形结构
     * @param menusList 员工权限列表
     * @return
     */
    private List<Menu> getMenuTree(List<Menu> menusList) {
        //1、new 一个 List 集合，存放数据
        ArrayList<Menu> resultMenuList = new ArrayList<>();//权限列表

        for (Menu menu: menusList) {
            //2、继续遍历，寻找子节点
            for (Menu e: menusList) {
                if (e.getParentId().equals(menu.getId())){
                    menu.getChildren().add(e);
                }
            }
            //3、如果 ParentId = 0，表示此权限就是顶级父级菜单
            if (menu.getParentId()==0){
                resultMenuList.add(menu);
            }
        }
        return resultMenuList;
    }

    /**
     * 角色信息 -- 导出 Excel
     * @param response
     * @return
     */
    @Override
    public void outExcel(HttpServletResponse response) {
        try{
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            //1、 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("权限基本信息表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            //2、查询数据库数据
            LambdaQueryWrapper<Menu> qw = new LambdaQueryWrapper<>();
            List<Menu> menus = menuMapper.selectList(qw);

            //3、设置要排除的字段
            HashSet<String> set = new HashSet<>();
            set.add("path"); //权限路径
            set.add("parentId"); //权限父子级 id
            set.add("orderId"); //权限排序 id
            set.add("children"); //子菜单

            EasyExcel.write(response.getOutputStream(),Menu.class)
                    .sheet("权限基本信息表")
                    .excludeColumnFiledNames(set)
                    // 自定义 Converter 接口 实现类
                    .registerConverter(new ListStringConverter())
                    .doWrite(menus);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
